package chess;
import java.awt.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;

import transfer.ChatData;
import transfer.ChessData;
import transfer.Data;
import util.Utils;

import client.Client;

import chessman.Bishop;
import chessman.Chessman;
import chessman.King;
import chessman.Knight;
import chessman.Pawn;
import chessman.Queen;
import chessman.Rook;


public class Board extends JPanel {
	/**
	 * 
	 */
	private static final long serialVersionUID = -898990689981817737L;
	// Client
	private Client client;
	// intialize variables
	private Image boardImage1;
	private Image boardImage2;
	// intialize components
	private JPanel centerPanel = new JPanel();
	private JPanel southPanel = new JPanel();
	private JPanel westPanel = new JPanel();
	// initialze arrays to hold panels and images of the board
	private JLabel[] labels = new JLabel[64];
	public MyMouseListener getMouseListener() {
		return mouseListener;
	}

	public void setMouseListener(MyMouseListener mouseListener) {
		this.mouseListener = mouseListener;
	}

	private ImagePanel[] panels = new ImagePanel[64];
	// array chessman
	private Chessman[] arrayChess = new Chessman[64];

	public Chessman[] getArrayChess() {
		return arrayChess;
	}

	public void setArrayChess(Chessman[] arrayChess) {
		this.arrayChess = arrayChess;
	}

	// border
	private Border redLine = BorderFactory.createLineBorder(Color.GREEN, 1,
			false);
	private Border empty = BorderFactory.createEmptyBorder();

	private MyMouseListener mouseListener = new MyMouseListener(this);

	public Board(Client client) throws IOException {
		this.boardImage1 = ImageIO.read(new File("Resources/Images/black-piece.png"));
		this.boardImage2 = ImageIO.read(new File("Resources/Images/white-piece.png"));
		this.client = client;
		createAndShowGUI();// call method to create gui

		// init teamA
		this.addChessman(56, Rook.getInstanceTeamA());
		this.addChessman(63, Rook.getInstanceTeamA());
		this.addChessman(57, Knight.getInstanceTeamA());
		this.addChessman(62, Knight.getInstanceTeamA());
		this.addChessman(58, Bishop.getInstanceTeamA());
		this.addChessman(61, Bishop.getInstanceTeamA());
		this.addChessman(60, Queen.getInstanceTeamA());
		this.addChessman(59, King.getInstanceTeamA());
		for (int i = 48; i < 56; i++) {
			this.addChessman(i, Pawn.getInstanceTeamA());
		}
		// init teamB
		this.addChessman(0, Rook.getInstanceTeamB());
		this.addChessman(7, Rook.getInstanceTeamB());
		this.addChessman(1, Knight.getInstanceTeamB());
		this.addChessman(6, Knight.getInstanceTeamB());
		this.addChessman(2, Bishop.getInstanceTeamB());
		this.addChessman(5, Bishop.getInstanceTeamB());
		this.addChessman(4, Queen.getInstanceTeamB());
		this.addChessman(3, King.getInstanceTeamB());
		for (int i = 8; i < 16; i++) {
			this.addChessman(i, Pawn.getInstanceTeamB());
		}

	}

	private void createAndShowGUI() {
		/*
		 * setTitle("Chess board example");
		 * 
		 * setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		 * setResizable(false);
		 */
		// addComponentsToPane(getContentPane());

		// setSize(600, 600);
		// setLocationRelativeTo(null);
		setVisible(true);
		this.setLayout(new BorderLayout());
		addComponentsToPane(this);
	}

	/**
	 * Adds all the necessary components to the content pane of the JFrame, and
	 * adds appropriate listeners to components.
	 */
	private void addComponentsToPane(Container contentPane) {

		GridLayout gridLayout = new GridLayout(8, 8);
		centerPanel.setLayout(gridLayout);

		// call mehod to add labels to south panel
		addLabelsToSouthPanel();
		// call method to add oanels to west panel
		addLabelsToWestPanel();
		// call method to add panels and labels to the center panel which holds
		// the board
		addPanelsAndLabels();
		// add all panels to frame
		contentPane.add(centerPanel, BorderLayout.CENTER);
		contentPane.add(southPanel, BorderLayout.SOUTH);
		contentPane.add(westPanel, BorderLayout.WEST);
	}

	private void addLabelsToSouthPanel() {
		GridLayout gridLayout = new GridLayout(0, 8);

		southPanel.setLayout(gridLayout);
		JLabel[] lbls = new JLabel[8];
		String[] label = { "A", "B", "C", "D", "E", "F", "G", "H" };

		for (int i = 0; i < 8; i++) {
			lbls[i] = new JLabel(label[i] + "");
			southPanel.add(lbls[i]);
		}
	}

	private void addLabelsToWestPanel() {
		GridLayout gridLayout = new GridLayout(8, 0);

		westPanel.setLayout(gridLayout);
		JLabel[] lbls = new JLabel[8];
		int[] num = { 8, 7, 6, 5, 4, 3, 2, 1 };
		for (int i = 0; i < 8; i++) {
			lbls[i] = new JLabel(num[i] + "");
			westPanel.add(lbls[i]);
		}
	}

	private void addPanelsAndLabels() {

		// call methd to create panels with backgound images and appropriate
		// names
		addPanelsAndImages();

		for (int i = 0; i < panels.length; i++) {
			labels[i] = new JLabel();

			// used to know the postion of the label on the board
			labels[i].setName(panels[i].getName());

			panels[i].setLayout(new BoxLayout(panels[i], BoxLayout.X_AXIS));
			panels[i].add(Box.createHorizontalGlue());
			panels[i].add(labels[i]);
			panels[i].add(Box.createHorizontalGlue());

			// add mouse listener
			panels[i].addMouseListener(mouseListener);
			// labels[i].addMouseListener(mouseListener);

			// adds panels created in addPanelsAndImages()
			centerPanel.add(panels[i]);
		}
	}

	// this method will create panels with backround images of chess board and
	// set its name according to 1-8 for rows and A-H for coloumns
	private void addPanelsAndImages() {
		int count = 0;
		String[] label = { "A", "B", "C", "D", "E", "F", "G", "H" };
		int[] num = { 8, 7, 6, 5, 4, 3, 2, 1 };

		for (int row = 0; row < 8; row++) {
			for (int col = 0; col < 8; col++) {
				if ((col + row) % 2 == 0) {// even numbers get white pieces
					panels[count] = new ImagePanel(boardImage1);
				} else {// odd numbers get black pieces
					panels[count] = new ImagePanel(boardImage2);
				}

				panels[count].setName(label[col] + num[row]);
				panels[count].setIndexPosition(count);
				count++;
			}
		}
	}

	// method sets image of a label at a certain position in the board according
	// to the block name i.e D4
	public void addPiece(ImageIcon img, String block) {
		for (int s = 0; s < labels.length; s++) {
			if (labels[s].getName().equalsIgnoreCase(block)) {
				labels[s].setIcon(img);
			}
		}
	}

	public void addChessman(int indexPosition, Chessman chessman) {
		Chessman temp = null;
		try {
			temp = (Chessman) chessman.clone();
			labels[indexPosition].setIcon(temp.getIcon());
			temp.setPositionWithIndex(indexPosition);
			arrayChess[indexPosition] = temp;
			panels[indexPosition].setChessman(temp);
			System.out.println("da dat tai vi tri:" + temp.getStringPosition());
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void setChessmanOnBoard(int indexPostion, Chessman chessman) {
		if (chessman != null) {
			chessman.setPositionWithIndex(indexPostion);
		}
		arrayChess[indexPostion] = chessman;

	}

	public void enablePieceBorder(String block) {
		for (int s = 0; s < labels.length; s++) {
			if (labels[s].getName().equalsIgnoreCase(block)) {
				panels[s].setBorder(redLine);
			}
		}
	}

	public void disableAllPieceBorder() {
		for (int s = 0; s < panels.length; s++) {

			panels[s].setBorder(empty);
		}
	}

	public boolean moveChessman(ImagePanel select, ImagePanel target) {
		Chessman chessSelect = select.getChessman();
		boolean endGame = false;
		String result = null;
		if (chessSelect.canMove(arrayChess)
				.contains(target.getStringPosition())) {
			int targetPosition = target.getIndexPosition();
			int selectPosition = select.getIndexPosition();
			Chessman chessTarget = target.getChessman();
			if (chessTarget != null) {// kiem tra o target co chua
												// chessman hay ko
				arrayChess[targetPosition] = null;
				if(chessTarget instanceof King){
					if(chessTarget.equals(King.getInstanceTeamA())){
						result = "Team B Win";
					}
					else{
						result = "Team A Win";
					}
					endGame = true;
				}
			}
			setChessmanOnBoard(selectPosition, null);
			if (chessSelect instanceof Pawn) {
				if (targetPosition < 8 && chessSelect.getTeam() == 0) {
					chessSelect = Queen.getInstanceTeamA();// pawn o team A da
															// den hang 0
				}
				if (targetPosition > 55 && chessSelect.getTeam() == 1) {
					chessSelect = Queen.getInstanceTeamB();// pawn o team B da
															// den hang 7
				}
			}
			setChessmanOnBoard(targetPosition, chessSelect);

			refreshBoard();
			
			// send data 
			Data data = new ChessData("Finish turn",arrayChess,Utils.currentRoomID);
			client.getCw().sendObject(data);
			if(endGame){
				client.getCw().sendObject(new ChatData("End Game", Utils.currentRoomID, result));
			}
			
			return true;
		}
		return false;
	}

	public void refreshBoard() {
		this.removeAll();
		centerPanel = new JPanel();
		southPanel = new JPanel();
		westPanel = new JPanel();

		createAndShowGUI();
		for (int s = 0; s < arrayChess.length; s++) {
			if (arrayChess[s] != null) {
				panels[s].setChessman(arrayChess[s]);
				labels[s].setIcon(panels[s].getChessman().getIcon());

			}
		}
		revalidate();
	}

}